package cn.coder.jdbc.core;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Set;

import cn.coder.jdbc.annotation.Column;
import cn.coder.jdbc.annotation.Id;
import cn.coder.jdbc.annotation.Table;
import cn.coder.jdbc.util.FieldUtils;

/**
 * 带注解的对象映射类
 * @author YYDF
 *
 */
public final class EntityMapping {

	private String tableName;
	private String[] columns;
	private String[] primaryKeys;
	private Field generateKeyField;

	public EntityMapping(Class<?> clazz) {
		findTable(clazz);
		findColumns(clazz);
	}
	
	private void findTable(Class<?> clazz) {
		Table table = clazz.getAnnotation(Table.class);
		if (table == null)
			throw new NullPointerException("The 'Table' annotation not found");
		this.tableName = table.value();
	}
	
	private void findColumns(Class<?> clazz) {
		Column col;
		ArrayList<String> columnList = new ArrayList<>();
		ArrayList<String> primaryKeyList = new ArrayList<>();
		Set<Field> fields = FieldUtils.getDeclaredFields(clazz);
		int num = 0;
		for (Field field : fields) {
			col = field.getAnnotation(Column.class);
			if (col != null) {
				num++;
				columnList.add(col.value());
				Id id = field.getAnnotation(Id.class);
				if (id != null) {
					primaryKeyList.add(col.value());
					if (id.value()) {
						this.generateKeyField = field;
					}
				}
			}
		}
		if (num == 0)
			throw new NullPointerException("The 'Column' annotation not found");
		
		this.columns = new String[columnList.size()];
		columnList.toArray(this.columns);
		this.primaryKeys = new String[primaryKeyList.size()];
		primaryKeyList.toArray(this.primaryKeys);
	}

	public String[] getColumns() {
		return this.columns;
	}

	public String getTable() {
		return this.tableName;
	}

	public String[] getPrimaryKeys() {
		return this.primaryKeys;
	}

	public Field getGenerateKeyField() {
		return this.generateKeyField;
	}

	public boolean findColumn(String name) {
		return findIndex(this.columns, name);
	}

	public boolean findPrimaryKey(String name) {
		return findIndex(this.primaryKeys, name);
	}

	private static boolean findIndex(String[] arr, String key) {
		int len = arr.length;
		if (len > 0) {
			for (int i = 0; i < len; i++) {
				if (arr[i].compareTo(key) == 0) {
					return true; // key found.
				}
			}
		}
		return false;// key not found.
	}
}
